﻿using System;
using System.Collections.Generic;
using System.Web.UI;
using hedefgrup.reports.common;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
using hedefgrup.reports.common.SSRD;

/// <summary>
/// Summary description for index
/// </summary>
public partial class index : reportPage
{
    private StringBuilder reportListBuilder;
    private Dictionary<int, Type> reportTypeCache = new Dictionary<int, Type>();
    private SortedList<string, int> sortedReportTypeCache = new SortedList<string, int>();

    private void FillReportList()
    {
        if (reportListBuilder == null)
        {
            lock (this)
            {
                if (reportListBuilder == null)
                {
                    Type[] reportTypes = typeof(Report_Abstract).Assembly.GetTypes();
                    foreach (Type reportType in reportTypes)
                    {
                        if (typeof(Report_Abstract).IsAssignableFrom(reportType) && !reportType.IsAbstract)
                        {
                            int reportTypeHashCode = Math.Abs(reportType.AssemblyQualifiedName.GetHashCode());
                            Report_Abstract reportInstance = Activator.CreateInstance(reportType) as Report_Abstract;
                            reportInstance.Context.CompatibleProjectName = base.userProjectName;
                            reportInstance.Context.User = user.Current;
                            sortedReportTypeCache.Add(reportInstance.SortPrefix, reportTypeHashCode);
                            reportTypeCache.Add(reportTypeHashCode, reportType);
                        }
                    }

                    StringBuilder reportListBuilderLocalScope = new StringBuilder();
                    foreach (int reportTypeHashCode in sortedReportTypeCache.Values)
                    {
                        Report_Abstract reportInstance = Activator.CreateInstance(reportTypeCache[reportTypeHashCode]) as Report_Abstract;
                        reportInstance.Context.CompatibleProjectName = base.userProjectName;
                        reportInstance.Context.User = user.Current;
                        if (reportInstance.SupportsProject(base.userProjectName) && reportInstance.Authorized)
                        {
                            reportListBuilderLocalScope.AppendFormat("<a href=\"?r={0}\">{1}</a>{2}", reportTypeHashCode, reportInstance.DisplayName, HR);
                        }
                    }
                    reportListBuilder = reportListBuilderLocalScope;
                }
            }
        }

        reports.Text = reportListBuilder.ToString();
    }

    private void SetCriteriaValueAndFillCriteriaValueList(Report_Abstract reportInstance, HtmlSelect htmlSelect, string criteriaName, string postedValue, string disabledValue)
    {
        Filter criteria = reportInstance.GetCriteriaByName(criteriaName);

        if (criteria != null)
        {
            if (!string.IsNullOrEmpty(postedValue))
            {
                criteria.Values.Clear();
                criteria.Values.Add(postedValue);
            }

            string[] criteriaValueList = criteria.GetValueList();
            foreach (string criteriaValue in criteriaValueList)
            {
                ListItem criteriaValueListItem = new ListItem(criteriaValue, criteriaValue);
                if (criteriaValue == postedValue)
                {
                    criteriaValueListItem.Selected = true;
                }
                htmlSelect.Items.Add(criteriaValueListItem);
            }
        }
        else
        {
            htmlSelect.Items.Add(new ListItem(disabledValue, disabledValue));
            htmlSelect.Disabled = true;
        }
    }

    private string ToFilterText(string currentFilter)
    {
        hedefgrup.reports.common.Tree questionnaire = hedefgrup.reports.common.Report_Abstract.Current.Context.Questionnaire;
        hedefgrup.reports.common.Tree question = questionnaire.GetChild(currentFilter);
        if (question != null)
        {
            return currentFilter + ": " + question.Text;
        }
        else
        {
            return currentFilter;
        }
    }

    private string ToFilterValuesText(Filter appliedFilter)
    {
        StringBuilder valuesBuilder = new StringBuilder();

        hedefgrup.reports.common.Tree questionnaire = hedefgrup.reports.common.Report_Abstract.Current.Context.Questionnaire;
        hedefgrup.reports.common.Tree question = questionnaire.GetChild(appliedFilter.Name);

        foreach (string value in appliedFilter.Values)
        {
            if (question != null)
            {
                hedefgrup.reports.common.Tree option = question.GetChild(value);
                if (option != null)
                {
                    valuesBuilder.AppendFormat("{0}: {1} | ", option.Key, option.Text);
                }
                else
                {
                    valuesBuilder.AppendFormat("{0} | ", value);
                }
            }
            else
            {
                valuesBuilder.AppendFormat("{0} | ", value);
            }
        }
        valuesBuilder.Length -= 3;
        return valuesBuilder.ToString();
    }

    private bool IsIE7
    {
        get
        {
            return Request.UserAgent.Contains("MSIE 7");
        }
    }

    protected string HR
    {
        get
        {
            return IsIE7 ? "" : "<hr />";
        }
    }

    private void GenerateReport()
    {
        if (Request.QueryString.Keys.Count == 1 && Request.QueryString.Keys[0] == "r")
        {
            int reportTypeHashCode;

            if (!int.TryParse(Request.QueryString["r"], out reportTypeHashCode))
            {
                return;
            }

            if (!reportTypeCache.ContainsKey(reportTypeHashCode))
            {
                return;
            }

            r.Value = reportTypeHashCode.ToString();
            Type reportType = reportTypeCache[reportTypeHashCode];
            Report_Abstract.Current = Activator.CreateInstance(reportType) as Report_Abstract;

            ReportContext reportContext = Report_Abstract.Current.Context;

            reportContext.ApplicationPath = Server.MapPath("/");
            reportContext.AudioFilesPath = Server.MapPath("/m/" + base.userProjectName);
            reportContext.Project = hedefgrup.reports.common.Tree.Root.GetChild(base.userProjectName.ToUpperInvariant());
            reportContext.Questionnaire = reportContext.Project.GetChild("QUESTIONNAIRE");
            reportContext.Organization = hedefgrup.reports.common.Tree.Root.GetChild("QVN2013").GetChild("ORGANIZATION");
            reportContext.TableName = reportContext.Project["Table"];
            reportContext.CompatibleProjectName = base.userProjectName;
            reportContext.User = user.Current;
        }

        projectName.Text = hedefgrup.reports.common.Tree.Root.GetChild(base.userProjectName.ToUpperInvariant()).Text;

        Report_Abstract reportInstance = Report_Abstract.Current;

        if (reportInstance != null)
        {
            Stopwatch timeTakenChronometer = Stopwatch.StartNew();

            if (Request.QueryString["RemoveAllFilters"] == "1")
            {
                foreach (Filter appliedFilter in reportInstance.GetAppliedFilters())
                {
                    appliedFilter.Values.Clear();
                }
            }

            StringBuilder appliedFiltersBuilder = new StringBuilder();
            foreach (Filter appliedFilter in reportInstance.GetAppliedFilters())
            {
                appliedFiltersBuilder.AppendFormat("Filtre {0}: {1}<br/>", ToFilterText(appliedFilter.Name), ToFilterValuesText(appliedFilter));
            }

            if (appliedFiltersBuilder.Length > 0)
            {
                appliedFiltersText.Text = "<br/>" + appliedFiltersBuilder.ToString();
            }

            ReportDisplayName.Text = "(" + reportInstance.DisplayName + ")";

            Filter[] appliedFilters = reportInstance.GetAppliedFilters();

            if (appliedFilters.Length > 0)
            {
                DeleteFilters.Src = DeleteFilters.Src.Replace("_gray", "");
            }
            else
            {
                DeleteFilters_A.Attributes["onclick"] = "";
            }

            string beginMonthString = Request.QueryString["BeginMonth"];
            string endMonthString = Request.QueryString["EndMonth"];
            string rollString = Request.QueryString["Roll"];
            string networkString = Request.QueryString["Network"];
            string organizationString = Request.QueryString["Organization"];
            string ssmPeriodString = Request.QueryString["SSMPeriod"];

            SetCriteriaValueAndFillCriteriaValueList(reportInstance, BeginMonth, "Begin Month", beginMonthString, "yyyymm");
            SetCriteriaValueAndFillCriteriaValueList(reportInstance, EndMonth, "End Month", endMonthString, "yyyymm");
            SetCriteriaValueAndFillCriteriaValueList(reportInstance, Roll, "Roll", rollString, "Yok");
            SetCriteriaValueAndFillCriteriaValueList(reportInstance, Network, "Network", networkString, Criteria_Network.AllNetworks);
            SetCriteriaValueAndFillCriteriaValueList(reportInstance, SSMPeriod, "SSM Period", ssmPeriodString, Criteria_SSRD_SSMPeriod.PleaseSelect);
            SetCriteriaValueAndFillCriteriaValueList(reportInstance, Organization, "Organization", organizationString, Criteria_Organization.AllOrganizations);

            if (base.userProjectName != Global.PROJECT_SSRD)
            {
                SSMPeriodPlaceHolder.Visible = false;
            }
            else
            {
                NetworkPlaceholder.Visible = false;
            }

            if (organizationString == "Dacia")
            {
                reportInstance.Context.Organization = hedefgrup.reports.common.Tree.Root.GetChild("QVN2013").GetChild("DACIA_ORGANIZATION");
            }
            else
            {
                reportInstance.Context.Organization = hedefgrup.reports.common.Tree.Root.GetChild("QVN2013").GetChild("ORGANIZATION");
            }

            ReportResult results = reportInstance.GenerateReport();

            StringBuilder reportHtmlBuilder = new StringBuilder("<table ");
            if (IsIE7)
            {
                reportHtmlBuilder.Append("style=\"width:95%\" ");
            }
            reportHtmlBuilder.Append("/>");

            if (results.HeaderRows.Count > 0)
            {
                reportHtmlBuilder.Append("<thead>");
                foreach (Row headerRow in results.HeaderRows)
                {
                    reportHtmlBuilder.Append("<tr>");
                    foreach (Cell headerCell in headerRow.Cells)
                    {
                        reportHtmlBuilder.AppendFormat
                        (
                            "<th{0}{1}>{2}</th>",
                            headerCell.Span > 0 ? " colspan=\"" + headerCell.Span + "\"" : "",
                            headerCell.TextAlign != null ? " style=\"text-align:" + headerCell.TextAlign + "\"" : "",
                            headerCell.Text
                        );
                    }

                    reportHtmlBuilder.Append("</tr>");
                }
                reportHtmlBuilder.Append("</thead>");
            }

            reportHtmlBuilder.Append("<tbody>");

            foreach (Row reportRow in results.GetRows())
            {
                reportHtmlBuilder.Append("<tr>");
                foreach (Cell reportCell in reportRow.Cells)
                {
                    reportHtmlBuilder.AppendFormat
                    (
                        "<td{0}{1}>{2}</td>",
                        reportCell.Span > 0 ? " colspan=\"" + reportCell.Span + "\"" : "",
                        GetCellStyle(reportCell),
                        reportCell.Text
                    );
                }
                reportHtmlBuilder.Append("</tr>");
            }

            reportHtmlBuilder.Append("</tbody></table>");

            report.Text = reportHtmlBuilder.ToString();

            criteria.Visible = true;

            timetaken.Text = timeTakenChronometer.Elapsed.TotalMilliseconds.ToString() + " ms&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
        }
    }

    private string GetCellStyle(Cell cell)
    {
        if (cell.Color != null || cell.TextAlign != null || cell.Bold)
        {
            return
                " style=\"" +
                (cell.Color != null ? "color:" + cell.Color + ";" : "") +
                (cell.TextAlign != null ? "text-align:" + cell.TextAlign + ";" : "") +
                (cell.Bold ? "font-weight:bold;" : "") +
                "\"";
        }
        else
        {
            return null;
        }
    }

    private void CheckAuth()
    {
        if (user.Current == null)
        {
            Response.Redirect("login.aspx");
        }

        administrative_tasks.Visible = user.Current.getIsAdministrator();
    }

    protected void Page_Load()
    {
        CheckAuth();

        FillReportList();

        GenerateReport();
    }
}